using System;
using System.Collections.Generic;
using System.Text;

using NSimpleDB.Service.Contract;

namespace NSimpleDB.SimpleDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Simple NSimpleDB Demo");

            ISimpleDBService simpleDb;

            string accessKeyId;
            string secretAccessKey;

            accessKeyId = Prompt("Amazon access key id [enter for local mode]");
            if (accessKeyId != "")
            {
                secretAccessKey = Prompt("Amazon secret access key");
                simpleDb = new NSimpleDB.Service.Amazon.AmazonSimpleDBService(accessKeyId, secretAccessKey);

                Console.WriteLine("\nRunning online...\n");
            }
            else
            {
                simpleDb = new NSimpleDB.Service.VistaDb.VistaDbSimpleDBService("simpleDemo.vdb3");
                Console.WriteLine("\nRunning locally...\n");
            }
            try
            {
                simpleDb.CreateDomain("Contacts");

                bool exit = false;
                while (!exit)
                {
                    Console.Write("N(ew contact, E(dit, D(elete, L(ist, C(lear domain, eX(it: ");
                    switch (Console.ReadLine().ToLower())
                    {
                        case "n":
                            EnterNewContact(simpleDb);
                            break;
                        case "e":
                            EditContact(simpleDb);
                            break;
                        case "d":
                            DeleteContact(simpleDb);
                            break;
                        case "l":
                            ListContacts(simpleDb);
                            break;
                        case "c":
                            ClearDomain(simpleDb);
                            exit = true;
                            break;
                        case "x":
                            exit = true;
                            break;
                    }
                }
            }
            finally
            {
                simpleDb.Close();
            }
        }


        private static void ClearDomain(ISimpleDBService simpleDb)
        {
            Console.WriteLine("Deleting domain...");
            simpleDb.DeleteDomain("contacts");
            Console.WriteLine("Domain deleted!");
        }

        private static void DeleteContact(ISimpleDBService simpleDb)
        {
            string contactId = GetContactId(simpleDb);
            if (contactId != "")
            {
                simpleDb.DeleteAttributes("Contacts", contactId, new string[] { });
                Console.WriteLine("  Contact deleted!");
            }
        }


        private static void EditContact(ISimpleDBService simpleDb)
        {
            string contactId = GetContactId(simpleDb);
            if (contactId != "")
            {
                #region show contact to edit
                ISimpleDBAttribute[] contact = simpleDb.GetAttributes("Contacts", contactId);
                Console.WriteLine("  Found: {0}, {1}, {2}", contact[0].Value, contact[1].Value, contact[2].Value);
                #endregion
                #region enter new contact data
                string name = Prompt("Name");
                string city = Prompt("City");
                string phone = Prompt("Phone#");

                List<ISimpleDBAttribute> attrToReplace = new List<ISimpleDBAttribute>();
                if (name != "") attrToReplace.Add(new SimpleDBAttribute("name", name, true));
                if (city != "") attrToReplace.Add(new SimpleDBAttribute("city", city, true));
                if (phone != "") attrToReplace.Add(new SimpleDBAttribute("phone", phone, true));

                if (attrToReplace.Count > 0)
                {
                    simpleDb.PutAttributes("Contacts", contactId, attrToReplace.ToArray());
                    Console.WriteLine("  Stored contact");
                }
                #endregion
            }
        }


        private static string GetContactId(ISimpleDBService simpleDb)
        {
            string pattern = Prompt("Index# or name");
            try
            {
                int contactIndex = int.Parse(pattern);
                string[] contactIds = simpleDb.Query("Contacts", "['name'>' ']");
                if (contactIndex < 0 || contactIndex >= contactIds.Length)
                    return "";
                else
                    return contactIds[contactIndex];
            }
            catch
            {
                string[] contactIds = simpleDb.Query("Contacts", string.Format("['name' starts-with '{0}']", pattern));
                if (contactIds.Length > 0)
                    return contactIds[0];
                else
                    return "";
            }
        }


        private static void EnterNewContact(ISimpleDBService simpleDb)
        {
            string name = Prompt("Name");
            if (name == "") return;

            string city = Prompt("City");
            string phone = Prompt("Phone#");

            simpleDb.PutAttributes("Contacts", Guid.NewGuid().ToString(),
                                   new SimpleDBAttribute("name", name),
                                   new SimpleDBAttribute("city", city),
                                   new SimpleDBAttribute("phone", phone));
        }


        private static void ListContacts(ISimpleDBService simpleDb)
        {
            string[] contactIds;

            contactIds = simpleDb.Query("Contacts", "['name'>'']");
            for (int i = 0; i < contactIds.Length; i++)
            {
                ISimpleDBAttribute[] contact = simpleDb.GetAttributes("Contacts", contactIds[i]);
                Console.WriteLine("  #{0} - {1}, {2}, {3}", i, contact[0].Value, contact[1].Value, contact[2].Value);
            }
            Console.WriteLine("  {0} contact(s)", contactIds.Length);
        }


        private static string Prompt(string label)
        {
            Console.Write("  {0}: ", label);
            return Console.ReadLine();
        }
    }
}
